##### configurable variables
CORE     ?= 1

AUTOENV  ?= ~/autoenv
TOOLHOME ?= C:/QX-IDE/plugins/QXTOOLS_1.0.0.202411121128/qxtools/toolchain/3slot_320f
TESTCASE ?=
PYTHON   ?= python
OSENV    ?=

CLANG_DEFINES ?=

##### Toolchain setting
ifneq (,$(findstring linux,$(OSTYPE)))
    CLANG := LD_LIBRARY_PATH=$(AUTOENV)/lib $(TOOLHOME)/bin/clang.bin
    AS    := $(TOOLHOME)/bin/as.bin
    LD    := $(TOOLHOME)/bin/ld.bin
else
    CLANG := $(TOOLHOME)/bin/clang
    AS    := $(TOOLHOME)/bin/as
    LD    := $(TOOLHOME)/bin/ld
endif

##### sources and objects
LIBS_DIR   ?= libs
DRIVER_DIR := ../$(LIBS_DIR)/driverlib
DEVICE_DIR := ../$(LIBS_DIR)/device
TESTS_DIR  := ../$(LIBS_DIR)/autotests

AUTOTESTS  ?= ../$(LIBS_DIR)/autotests

C_SOURCES   := main.c
C_SOURCES   += $(DEVICE_DIR)/device.c
C_SOURCES   += $(TESTS_DIR)/common.c
C_SOURCES   += $(wildcard $(DRIVER_DIR)/*.c)
TEST_SOURCE := $(AUTOTESTS)/$(TESTCASE)
START_FILE  := $(DEVICE_DIR)/startup.s

TEST_DIR         := $(dir $(TEST_SOURCE))
MODULE_NAME      := $(shell basename $(TEST_DIR))
SUBCOMMON_SOURCE += $(TEST_DIR)/subcommon.c

TARGET           := QXS320F28377L_driver_core$(CORE)
BUILD_DIR        := Build
MODULE_BUILD_DIR := $(BUILD_DIR)/$(MODULE_NAME)

##### Toolchain options for C2000 DSP
INC         := -I$(TOOLHOME)/include
INC         += -I$(DRIVER_DIR) -I$(DRIVER_DIR)/bit_field -I$(TESTS_DIR) -I$(DEVICE_DIR)
CLANG_FLAGS := -gdwarf-2 -O0 -mcpu=qx320f -target dsp
CLANG_FLAGS += -D__dsp__ -D__ELF__ -ffunction-sections -fdata-sections -c $(INC)
CLANG_FLAGS += -D__CORE$(CORE)__ $(CLANG_DEFINES) -MD

LDSCRIPT    := ldscript_DSPCore$(CORE).ld
LDFLAGS := -L ../$(LIBS_DIR)/ldscript -L ldscript -L $(TOOLHOME)/lib -L ../$(LIBS_DIR)
LDFLAGS += -T $(LDSCRIPT) -Map=$(BUILD_DIR)/linkMapFile --no-check-sections --gc-sections
LDFLAGS2 := -lm -lc -lrt -ldspsim

##### build rules

START_FILE_OBJ = $(addsuffix .o, $(basename $(notdir $(START_FILE))))
TEST_OBJ       = $(addsuffix .o, $(basename $(notdir $(TEST_SOURCE))))
SUBCOMMON_OBJ  = $(addsuffix .o, $(basename $(notdir $(SUBCOMMON_SOURCE))))
OBJECTS        = $(addprefix $(BUILD_DIR)/, $(START_FILE_OBJ))
OBJECTS       += $(addprefix $(MODULE_BUILD_DIR)/, $(TEST_OBJ))
OBJECTS       += $(addprefix $(MODULE_BUILD_DIR)/, $(SUBCOMMON_OBJ))
OBJECTS       += $(addprefix $(BUILD_DIR)/, $(notdir $(C_SOURCES:%.c=%.o)))

vpath %.c $(sort $(dir $(C_SOURCES)))
vpath %.s $(dir $(START_FILE))

.PHONY:all clean

all: $(BUILD_DIR)/$(TARGET).out

$(BUILD_DIR):
	@mkdir -p $@

$(MODULE_BUILD_DIR):
	@mkdir -p $@

$(BUILD_DIR)/$(TARGET).out: $(BUILD_DIR) $(MODULE_BUILD_DIR) $(OBJECTS)
	$(LD) $(LDFLAGS) -o $@ $(OBJECTS) $(LDFLAGS2)
	cd $(BUILD_DIR) && ../../postbuild.cmd $(TOOLHOME) $(TARGET) core$(CORE) --makefile-build
	cd $(BUILD_DIR) && cp -f $(TARGET).out ../Release/$(TARGET).out

$(BUILD_DIR)/$(START_FILE_OBJ): $(START_FILE)
	$(AS) -g $< -o $@

$(MODULE_BUILD_DIR)/$(TEST_OBJ): $(TEST_SOURCE)
	$(CLANG) $(CLANG_FLAGS) $< -o $@

$(MODULE_BUILD_DIR)/$(SUBCOMMON_OBJ): $(SUBCOMMON_SOURCE)
	$(CLANG) $(CLANG_FLAGS) $< -o $@

$(BUILD_DIR)/%.o: %.c
	$(CLANG) $(CLANG_FLAGS) $< -o $@

clean:
	rm -rf $(BUILD_DIR)/*

-include $(OBJECTS:.o=.d)
